package cn.xiangyunsoft.updater;

import com.sina.cloudstorage.SDKGlobalConfiguration;
import com.sina.cloudstorage.auth.AWSCredentials;
import com.sina.cloudstorage.auth.BasicAWSCredentials;
import com.sina.cloudstorage.services.scs.SCS;
import com.sina.cloudstorage.services.scs.SCSClient;
import com.sina.cloudstorage.services.scs.model.ObjectListing;
import com.sina.cloudstorage.services.scs.model.S3Object;

import java.io.*;
import java.util.ArrayList;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Created by libo on 2015/8/15.
 */
public class UpdaterImpl implements AutoUpdater {

    private final String BUCKET_NAME = "tmsoft4update";

    private final String REMOTE_INFO_FILE = "tm_currentVersion.txt";

    private AWSCredentials credentials = null;
    private SCS conn = null;
    private Config config;
    private String remoteVersion;
    private String remoteDate;
    private String remoteFileName;

    public UpdaterImpl() throws Exception {
        config = new Config();
        config.init();
        credentials = new BasicAWSCredentials(config.getAccessKey(), config.getSecretKey());
        conn = new SCSClient(credentials);
    }

    /**
     * 列bucket中所有文件
     */
    public void listObjects() {
        ObjectListing objectListing = conn.listObjects(BUCKET_NAME, "1.8");

    }


    /**
     * 读取远端信息.
     */
    public void readRemoteInfo() {
        SDKGlobalConfiguration.setGlobalTimeOffset(-60 * 5);//超时时间5分钟以后
        S3Object s3Obj = conn.getObject(BUCKET_NAME, REMOTE_INFO_FILE);
        InputStream in = s3Obj.getObjectContent();
        try {
            Properties properties = new Properties();
            properties.load(in);

            remoteVersion = properties.getProperty("version");
            remoteDate = properties.getProperty("date");
            remoteFileName = properties.getProperty("file");

            System.out.println("remoteVersion:" + remoteVersion);
            System.out.println("remoteDate:" + remoteDate);
            System.out.println("remoteFileName:" + remoteFileName);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            SDKGlobalConfiguration.setGlobalTimeOffset(0);
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 检查是否需要升级.
     *
     * @return
     */
    public boolean checkUpdate() {
        readRemoteInfo();

        return true;
    }

    public void executeUpdater() throws IOException {
        File file = downloadFile();
//        File file = new File("c:/temp/1.1_2015-8-15.zip");
        if (file != null) {
            stopService();
            decompression(file, config.getAppHome());
            doUpdateSql();
            startService();

            System.out.println("升级成功.请关闭本窗口.");
        }
    }

    private void doUpdateSql() {
        String cmd = config.getMySQL_HOME() + "\\bin\\mysql -uroot -p123456 < " + config.getAppHome() + "\\script\\update.sql";
//        String cmd = config.getMySQL_HOME() + "\\bin\\mysql -uroot -p123456 < " + config.getAppHome() + "\\script\\update.sql";
        execCmd(cmd);
    }

    public void stopService() {
        String cmd = "net stop Tomcat7";
        execCmd(cmd);
    }

    public void startService() {
        String cmd = "net start Tomcat7";
        execCmd(cmd);
    }

    public void execCmd(String cmd) {
        System.out.println("exec:" + cmd);
        BufferedReader input = null;
        try {
            String line;
            Process p = Runtime.getRuntime().exec(cmd);
            input = new BufferedReader(new InputStreamReader(p
                    .getInputStream()));
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void clean() {

    }

    public File downloadFile() {
        if (checkUpdate()) {
            SDKGlobalConfiguration.setGlobalTimeOffset(-60 * 5);//超时时间5分钟以后
            S3Object s3Obj = conn.getObject(BUCKET_NAME, remoteFileName);
            InputStream in = s3Obj.getObjectContent();
            byte[] buf = new byte[1024];
            OutputStream out = null;
            try {
                File file = new File(config.getTempPath() + remoteVersion + "_" + remoteDate + ".zip");
                out = new FileOutputStream(file);
                int count;
                while ((count = in.read(buf)) != -1) {
                    if (Thread.interrupted()) {
                        throw new InterruptedException();
                    }
                    out.write(buf, 0, count);
                }
                out.flush();
                return file;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                SDKGlobalConfiguration.setGlobalTimeOffset(0);
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public String remoteVersion() {
        return remoteVersion;
    }

    public String localVersion() {
        return config.getLocalVersion();
    }

    public String localUpdateDate() {
        return config.getLocalDate();
    }

    public String remoteDate() {
        return remoteDate;
    }

    /**
     * 解压缩文件.
     *
     * @param zipFile
     * @return
     */
    public ArrayList<String> decompression(File zipFile, String destPath) {
        ArrayList<String> allFileName = new ArrayList<String>();
        try {
            // 先指定压缩档的位置和档名，建立FileInputStream对象
            FileInputStream fins = new FileInputStream(zipFile);
            // 将fins传入ZipInputStream中
            ZipInputStream zins = new ZipInputStream(fins);
            ZipEntry ze = null;
            byte[] ch = new byte[256];
            while ((ze = zins.getNextEntry()) != null) {
                File zfile = new File(destPath + ze.getName());
                File fpath = new File(zfile.getParentFile().getPath());
                if (ze.isDirectory()) {
                    if (!zfile.exists())
                        zfile.mkdirs();
                    zins.closeEntry();
                } else {
                    if (!fpath.exists())
                        fpath.mkdirs();
                    FileOutputStream fouts = new FileOutputStream(zfile);
                    int i;
                    allFileName.add(zfile.getAbsolutePath());
                    while ((i = zins.read(ch)) != -1)
                        fouts.write(ch, 0, i);
                    zins.closeEntry();
                    fouts.close();
                }
            }
            fins.close();
            zins.close();
        } catch (Exception e) {
            System.err.println("Extract error:" + e.getMessage());
        }
        return allFileName;
    }

}
